package com.uinnova.product.eam.base.util;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 锁帮助类，之后可通过该类将单体对象锁修改为redis分布式锁
 * 
 * @author uinnova
 *
 */
public final class LockUtil {
	private static final String prefix = "dmv::lock::";
	private static final Map<String, ReentrantLock> lockMap = new ConcurrentHashMap<String, ReentrantLock>();

	/**
	 * 检查锁是否被占用
	 * @param lockName
	 * @return
	 * 	{@code true} 锁已被某线程持有
	 * 	{@code false} 锁没有被占用或该锁不存在
	 */
	public static boolean checkLock(String lockName) {
		LockUtil.putLockByLockName(lockName);
		return lockMap.get(lockName).isLocked();
	}
	/**
	 * 尝试抢占锁
	 * @param lockName
	 * @return
	 * 	{@code true}锁抢占成功
	 * 	{@code false} 抢锁失败
	 */
	public static boolean tryLock(String lockName) {
		LockUtil.putLockByLockName(lockName);
		return lockMap.get(lockName).tryLock();
	}
	/**
	 * 抢占锁，阻塞式处理
	 * @param lockName
	 */
	public static void lock(String lockName) {
		LockUtil.putLockByLockName(lockName);
		lockMap.get(lockName).lock();
	}
	/**
	 * 解锁
	 * @param lockName
	 */
	public static void unLock(String lockName) {
		if (lockMap.get(lockName) != null) {
			lockMap.get(lockName).unlock();
		}
	}

	/**
	 * 为锁实例化
	 * @param lockName
	 */
	private static void putLockByLockName(String lockName) {
		if (lockMap.get(lockName) == null) {
			synchronized (LockUtil.prefix + lockName) {
				if (lockMap.get(lockName) == null) {
					lockMap.put(lockName, new ReentrantLock());
				}
			}
		}
	}

}
